package com.neusoft.hifly;

import java.time.Duration;
import java.util.Properties;

import org.apache.ibatis.mapping.DatabaseIdProvider;
import org.apache.ibatis.mapping.VendorDatabaseIdProvider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.netflix.hystrix.EnableHystrix;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.web.context.request.RequestContextListener;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;

import com.netflix.hystrix.contrib.metrics.eventstream.HystrixMetricsStreamServlet;

/**
 * Title: 短信服务
 * <p>
 * Description: 启动
 * <p>
 * Copyright: 2019
 * <p>
 * Company: 东软汉枫
 *
 * @author lh_neu
 * @version 1.0.0
 */
@EnableDiscoveryClient
@EnableFeignClients
@EnableHystrix
@EnableHystrixDashboard
@EnableAsync
@RefreshScope
@EnableCaching(proxyTargetClass = true)
@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })
public class Application {

	public static void main(final String[] args) {
		SpringApplication.run(Application.class, args);
	}

	/**
	 * 跨域过滤器
	 *
	 * @return
	 */
	@Bean
	public CorsFilter corsFilter() {
		final UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
		final CorsConfiguration corsConfiguration = new CorsConfiguration();
		corsConfiguration.addAllowedOrigin("*");
		corsConfiguration.addAllowedHeader("*");
		corsConfiguration.addAllowedMethod("*");
		source.registerCorsConfiguration("/**", corsConfiguration); // 4
		return new CorsFilter(source);
	}

	//	/**
	//	 * 添加HTTP页面缓存
	//	 *
	//	 * @return 监听
	//	 */
	//	@Bean
	//	public FilterRegistrationBean shallowEtagHeaderFilter() {
	//		final FilterRegistrationBean registration = new FilterRegistrationBean();
	//		registration.setFilter(new ShallowEtagHeaderFilter());
	//		registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));
	//		registration.addUrlPatterns("/api/*"); // 只给接口进行缓存
	//		return registration;
	//	}

	/**
	 * 监听器：监听HTTP请求事件 解决RequestContextHolder.getRequestAttributes()空指针问题
	 *
	 * @return Listener
	 */
	@Bean
	public RequestContextListener requestContextListener() {
		return new RequestContextListener();
	}

	/**
	 * Mybatis设置:多数据库处理，根据数据库链接中的dialect信息，判断是哪种数据库
	 *
	 * @return 不同的数据库ID
	 */
	@Bean
	public DatabaseIdProvider getDatabaseIdProvider() {
		final DatabaseIdProvider databaseIdProvider = new VendorDatabaseIdProvider();
		final Properties properties = new Properties();
		properties.setProperty("Oracle", "oracle");
		properties.setProperty("SQL Server", "sqlserver");
		properties.setProperty("MySQL", "mysql");
		databaseIdProvider.setProperties(properties);
		return databaseIdProvider;
	}

	/**
	 * 服务容错可视化页面
	 *
	 * @return Servlet
	 */
	@Bean
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public ServletRegistrationBean getServlet() {
		final HystrixMetricsStreamServlet streamServlet = new HystrixMetricsStreamServlet();
		final ServletRegistrationBean registrationBean = new ServletRegistrationBean(streamServlet);
		registrationBean.setLoadOnStartup(1);
		registrationBean.addUrlMappings("/hystrix/hystrix.stream");
		registrationBean.setName("HystrixMetricsStreamServlet");
		return registrationBean;
	}

	/**
	 * TODO 配置Spring Cache和Redis整合
	 *
	 * @return CacheManager
	 */
	@Bean
	public CacheManager cacheManager(RedisConnectionFactory factory) {
		// 自定义的配置方法
		RedisCacheConfiguration defaultCacheConfig = RedisCacheConfiguration.defaultCacheConfig()
				// 设置缓存管理器管理的缓存的默认过期时间60分钟
				.entryTtl(Duration.ofMinutes(60))
				// 不缓存空值
				.disableCachingNullValues();
		return RedisCacheManager.builder(factory).cacheDefaults(defaultCacheConfig).build();
	}

}
